package com.stylefeng.guns.modular.qinhe.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.stylefeng.guns.GunsApplication;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.util.Hash;
import com.stylefeng.guns.modular.bean.Nav;
import com.stylefeng.guns.modular.bean.Texture;
import com.stylefeng.guns.modular.qinhe.service.ISuModelService;
import com.stylefeng.guns.modular.system.model.SuModel;
import com.stylefeng.guns.modular.system.service.IDictService;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.xml.bind.DatatypeConverter;
import jodd.io.FileNameUtil;
import jodd.io.FileUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller
@RequestMapping("/sutexture")
public class SuTextureController extends BaseController {

  public static final String PREFIX = "/qinhe/";
  @Autowired
  private IDictService dictService;
  @Autowired
  private ISuModelService suModelService;
  private final String homeDir =
      (new ApplicationHome(GunsApplication.class).getDir() + "/skm/textures/").replace("\\","/");

  @GetMapping("/list")
  public String list(
      @RequestParam(value = "directory", required = false, defaultValue = "") String directory,
      ModelMap modelMap) {
    String target = homeDir + directory;
    List<Nav> nav = new ArrayList<>();

    nav.add(new Nav("材质贴图",""));
    String[] split = directory.split("/");
    String prefix="";
    for (int i = 0; i < split.length; i++) {
      nav.add(new Nav(split[i],prefix+split[i]));
      prefix=(prefix+split[i]+"/");
    }
    modelMap.addAttribute("navs",nav);
    Supplier<Stream<Path>> streamSupplier = () -> {
      try {
        return Files.list(Paths.get(target));
      } catch (IOException e) {
        e.printStackTrace();
        return null;
      }
    };
    List<Texture> textures = new ArrayList<>();
    streamSupplier.get()
        .filter(path -> Files.isDirectory(path) || FileNameUtil.getBaseName(path.toString()).contains("-thumbnail"))
        .forEach(path -> textures
        .add(new Texture(!Files.isDirectory(path), FileNameUtil.getName(path.toString()),
            path.toString().replace("\\", "/").replace(homeDir, ""))
        ));
    modelMap.addAttribute("textures",textures);

    return PREFIX + "list_texture.html";
  }

  public static void main(String[] args) throws IOException {
    String home = "F:\\chen\\guns\\guns-admin\\target\\classes\\skm\\textures\\";
    Supplier<Stream<Path>> streamSupplier = () -> {
      try {
        return Files.list(Paths.get(home, "布纹"));
      } catch (IOException e) {
        e.printStackTrace();
        return null;
      }
    };
    Stream<Path> directories = streamSupplier.get().filter(path -> Files.isDirectory(path));
    directories.forEach(d -> {
      System.out.println(d.getFileName());
    });
    Stream<Path> imgFiles = streamSupplier.get().filter(path -> {
      System.out.println(path.getFileName());
      return path.toString().endsWith(".jpg");
    });
    imgFiles.forEach(System.out::println);
  }

  @GetMapping("/subfolder")
  @ResponseBody
  public Object getSubFolder(@RequestParam(value = "directory", required = false, defaultValue = "") String directory)
      throws IOException {

    Path dir = Paths.get(homeDir + directory);
    LinkedList<Nav> navs = Files.list(dir)
        .filter(path -> Files.isDirectory(path))
        .map(path -> new Nav(FileNameUtil.getBaseName(path.toString()),
            path.toString().replace("\\", "/").replace(homeDir, "")))
        .collect(Collectors.toCollection(LinkedList::new));
    int i = directory.lastIndexOf("/");
    navs.addFirst(new Nav("↰", StringUtils.isBlank(directory)?"":(dir.getParent().toString()+"/").replace("\\", "/").replace(homeDir, "")));
    return navs;
  }

  @PostMapping("/upload")
  @ResponseBody
  public Object uploadTexture(@RequestPart("file") MultipartFile zipFile,String folder)
      throws IOException {
    //解压,到指定folder
    File jarFolder = new ApplicationHome(GunsApplication.class).getDir();
    File targetFolder = new File(
        jarFolder + "/skm/textures/"+folder);

    ZipInputStream zis = new ZipInputStream(zipFile.getInputStream());
    ZipEntry zipEntry = zis.getNextEntry();
    byte[] buffer = new byte[1024];
    while (zipEntry != null) {
      File dest = new File(targetFolder,  zipEntry.getName());
      FileOutputStream fos = new FileOutputStream(
          dest);
      int len;
      while ((len = zis.read(buffer)) > 0) {
        fos.write(buffer, 0, len);
      }
      fos.close();
      zipEntry = zis.getNextEntry();
    }
    zis.closeEntry();
    zis.close();
    return "success";
  }



  @PostMapping("/upload/mat")
  @ResponseBody
  public Object upload(@RequestPart("file") MultipartFile zipFile,
      @RequestPart("thumb") MultipartFile thumbFile,
      @RequestParam String matname,
      @RequestParam Long category,
      @RequestParam(defaultValue = "0") Integer vray,
      @RequestParam(defaultValue = "0") Integer enscape,
      @RequestParam(defaultValue = "0") Integer thea) throws IOException {
    //保存到数据库
    SuModel suModel;
    //typ=1 su模型  [3:3d模型] [4:FBX模型] [5:UE4模型] type=2 表示是skm材
    long filename;
    suModel = new SuModel();
    filename = System.currentTimeMillis();
    suModel.setType(2);
    File jarFolder = new ApplicationHome(GunsApplication.class).getDir();
    File targetFile = new File(jarFolder + "/models/"+filename+".zip");
    File targetThumb = new File(jarFolder + "/models/"+filename+".png");
    zipFile.transferTo(targetFile);
    thumbFile.transferTo(targetThumb);
    String checksum = DatatypeConverter.printHexBinary(Hash.SHA256.checksum(targetFile)).toLowerCase();;
    suModel.setCategory(Long.parseLong(getPara("category")));
    suModel.setModelname(matname);
    suModel.setFilename(filename + "");
    suModel.setCreatetime(new Date());
    suModel.setUploader("shmiluyu");
    suModel.setFilesize(targetFile.length());
    suModel.setVray(vray);
    suModel.setEnscape(enscape);
    suModel.setThea(thea);
    suModel.setChecksum(checksum);
    suModelService.insert(suModel);
    return "success";
  }

  @GetMapping("/show/upload")
  public String showUploadPage(ModelMap modelMap){
    modelMap.put("cats",dictService.selectByParentCode("mat_cat"));
    return PREFIX+"show_mat_upload_page.html";
  }

  @GetMapping({"/list/mats/{categoryId}","/list/mats"})
  public String listMaterials(
      @PathVariable(value="categoryId",required = false) Long cid,
      @RequestParam(defaultValue = "nothing") String mats,
      ModelMap modelMap){
    modelMap.put("cats",dictService.selectByParentCode("mat_cat"));
    EntityWrapper<SuModel> wrapper = new EntityWrapper<>();
    if (cid != null) {
        wrapper.eq("category", cid);
    }
    if (StringUtils.contains(mats, "vray")) {
      wrapper.eq("vray", 1);
    }
    if (StringUtils.contains(mats, "enscape")) {
      wrapper.eq("enscape", 1);
    }
    if (StringUtils.contains(mats, "thea")) {
      wrapper.eq("thea", 1);
    }
    String[] split = mats.split(",");
    for (int i = 0; i < split.length; i++) {
      split[i] = StringUtils.wrap(split[i], "'");
    }
    modelMap.addAttribute("mats", StringUtils.join(split, ","));
    String page = getPara("page");
    if (StringUtils.isBlank(page)) {
      page = "1";
    }
    wrapper.eq("deleted", 0);
    wrapper.eq("type", 2);
    wrapper.orderBy("downloads", false);
    wrapper.orderBy("createtime",false);
    Page<SuModel> suModelPage = suModelService
        .selectPage(new Page<>(Integer.parseInt(page), 60), wrapper);
    modelMap.addAttribute("models", suModelPage);
    modelMap.addAttribute("cid",cid==null?"-1":cid.toString());
    return PREFIX+"list_materials.html";
  }

  @PostMapping("/delete/mat/{id}")
  @ResponseBody
  public Object deleteModel(@PathVariable Long id) {
    SuModel suModel = suModelService.selectById(id);
    suModel.setDeleted(1);
    String filename = suModel.getFilename();
    File jarFolder = new ApplicationHome(GunsApplication.class).getDir();
    File targetFile = new File(jarFolder + "/models/"+filename+".zip");
    File targetThumb = new File(jarFolder + "/models/"+filename+".png");
    try{
      FileUtil.deleteFile(targetFile);
      FileUtil.deleteFile(targetThumb);
    }catch (Exception ex){
      ex.printStackTrace();
    }
    suModelService.updateById(suModel);
    return SUCCESS_TIP;
  }
}
